package player.ui.controlbar;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JProgressBar;
import javax.swing.plaf.metal.MetalProgressBarUI;

import player.PS;
import player.miniplayer.PreviewFrame;
import player.miniplayer.SimpleMplayer;
import player.mplayer.MPlayerControl;

public class PlayerProgressBar extends JProgressBar{
	private static final long serialVersionUID = 3601756724283285144L;
	int maxValue=100000;
	int allTime=0;
	float rate=1;
	int nowTime=0;
	float sk=maxValue*0.01f;
	float sk2=maxValue*0.03f;
	boolean  dragSeekAvil=false;
	boolean  moveSeekAvil=false;
	Thread progressDragMonit ;
	Thread progressMoveMonit ;
	boolean isDraging=false;
	PreviewFrame previewFrame;
	boolean toVisible=false;
	long setVisibleTime=0;
	int visibleDelayTime=(int) (1.5*1000);
	PlayerProgressBar PlayerProgressBar;
	boolean isMouseOver=false;
	PlayerProgressBar(){
		super();
		PlayerProgressBar=this;
		this.setPreferredSize(new Dimension(2048,50));
		this.setBorder(null);
		this.setBorderPainted(false);
		this.setUI(new MetalProgressBarUI());
		PS.PlayerProgressBar=this;
		this.setMaximum(maxValue);
		this.setDoubleBuffered(true);
		this.addMouseListener(new MouseListener(){

			public void mouseClicked(MouseEvent e) {
				
			}

			public void mouseEntered(MouseEvent e) {
				updatePFBound(e.getLocationOnScreen());
			}

			public void mouseExited(MouseEvent e) {
				updatePFBound(e.getLocationOnScreen());
			}

			public void mousePressed(MouseEvent e) {
				setValue(getValueOnMouse(e.getPoint()));
				MPlayerControl.seekto(getTime());
				isDraging=true;
				if(previewFrame.isVisible()){
					SimpleMplayer.pausePlay();
				}
				hideNow();
				
			}

			public void mouseReleased(MouseEvent e) {
				isDraging=false;
			}
			
		});
		this.addMouseMotionListener(new MouseMotionListener(){

			public void mouseDragged(MouseEvent e) {
				setValue(getValueOnMouse(e.getPoint()));
				boolean b=false;
				if(isNP(e.getPoint())){
					b=true;
				}
				
				if(dragSeekAvil){
					b=true;
					progressDragMonit.interrupt();
				}
				if(b){
					MPlayerControl.seekto(getTime());
				}
				updatePFBound(e.getLocationOnScreen());
			}

			public void mouseMoved(MouseEvent e) {
				updatePFBound(e.getLocationOnScreen());
				setToVisible(true);
				boolean b=false;
				int time=0;
				if(previewFrame.isVisible()){
					Point p=PlayerProgressBar.getMousePosition();
					if(p!=null){
						time=getTimeOnMouse(p);
						if(isNP2(e.getPoint())){
							b=true;
						}
						if(moveSeekAvil){
							b=true;
							progressMoveMonit.interrupt();
						}
					}
					
				}
				if(b){
					SimpleMplayer.seekto(time);
				}
			}
			
		});
		
		progressDragMonit = new Thread() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(50);
						dragSeekAvil=true;
					} catch (InterruptedException e) {
					//	e.printStackTrace();
						dragSeekAvil=false;
					}
				}
			}
		};
		progressDragMonit.start();
		
		progressMoveMonit = new Thread() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(100);
						moveSeekAvil=true;
					} catch (InterruptedException e) {
					//	e.printStackTrace();
						moveSeekAvil=false;
					}
				}
			}
		};
		progressMoveMonit.start();
		
		previewFrame=new PreviewFrame();
		previewFrame.setVisible(true);
		
		new Thread(){
			public void run(){
				while(true){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					if(System.currentTimeMillis()-setVisibleTime>visibleDelayTime){
						if(toVisible){
							if(!previewFrame.isVisible()&PlayerProgressBar.isShowing()){
							
								if(PlayerProgressBar.isShowing()){
									Point p=PlayerProgressBar.getMousePosition();
									if(p!=null){
										previewFrame.setVisible(true);
										int time=getTimeOnMouse(p);
										SimpleMplayer.seekto(time);
									}
									
								}
								
							}
						}else{
							if(previewFrame.isVisible()){
								previewFrame.setVisible(false);
								SimpleMplayer.pausePlay();
							}
						}
					}
				}
			}
		}.start();
		
		
		
		SimpleMplayer.setWid(previewFrame.getWid());
		
		
		
		new Thread(){
			public void run(){
				while(true){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					Point p=PlayerProgressBar.getMousePosition();
					boolean b1=isMouseOver;
					if(p!=null){
						isMouseOver=true;
					}else{
						isMouseOver=false;
					}
					if(b1&!isMouseOver){
						setToVisible(false);
					}
					if(!b1&isMouseOver){
						setToVisible(true);
					}
				}
			}
		}.start();
		
	}
	
	boolean isNP(Point p){
		boolean b=false;
		int value=getValueOnMouse(p);
		float it=value%sk;
		if(it<100){
			b=true;
		}
		return b;
	}
	
	boolean isNP2(Point p){
		boolean b=false;
		int value=getValueOnMouse(p);
		float it=value%sk2;
		if(it<100){
			b=true;
		}
		return b;
	}
	
	void hideNow(){
		setToVisible(false);
		previewFrame.setVisible(false);
	}
	
	void setToVisible(boolean b){
		toVisible=b;
		setVisibleTime=System.currentTimeMillis();
	}
	
	void updatePFBound(Point mousePoint){
		if(this.isShowing()){
			Rectangle rec=getPreffredPFBound(mousePoint);
			previewFrame.setBounds(rec);
		}
	}
	
	Rectangle getPreffredPFBound(Point mousePoint){
		Rectangle rec=new Rectangle();
		rec.height=130;
		rec.width=(int) (rec.height*PS.videoRate);
		

		rec.height+=15;
		
		if(this.isShowing()){
			rec.y=this.getLocationOnScreen().y-rec.height-5;
		}
		
		rec.x=mousePoint.x-rec.width/2;
		return rec;
	}
	
	int getTimeOnMouse(Point point){
		float r=(float)point.getX()/getWidth();
		float value=getMaximum()*r;
		int time=(int) ((float)value/rate);
		return time;
	}
	
	
	
	int getValueOnMouse(Point p){
		float r=(float)p.getX()/getWidth();
		float value=getMaximum()*r;
		return (int) value;
	}
	
	public void setLength(int allTime){
		this.allTime=allTime;
		rate=(float)getMaximum()/allTime;
	}
	
	public void setNowTime(float time){
		int value=(int) (time*rate);
		setValue(value);
	}
	
	public void setValue(int value){
		super.setValue(value);
		nowTime=(int) ((float)value/rate);
		//repaint();
	}
	
	int getTime(){
		return nowTime;
	}
	
	
	
}
